#!/usr/bin/env node

// 使用动态导入支持ES模块
let ora;
(async () => {
    ora = (await import('ora')).default;
    
    const fs = require('fs').promises; // 导入文件系统模块
    const path = require('path'); // 导入路径模块

    /**
     * 脚手架主函数
     * 演示如何使用ora处理各种进度场景
     */
    async function scaffold() {
        console.log('🚀 开始创建React项目脚手架...\n');
        
        // 创建主进度spinner
        const mainSpinner = ora('正在初始化项目...').start();
        
        try {
            // 模拟项目初始化过程
            await simulateInitialization(mainSpinner);
            
            // 创建目录结构
            await createDirectoryStructure();
            
            // 创建配置文件
            await createConfigFiles();
            
            // 安装依赖
            await installDependencies();
            
            // 完成
            mainSpinner.succeed('✅ 项目创建完成！');
            console.log('\n🎉 您的React项目已成功创建！');
            console.log('📁 项目目录结构：');
            console.log('   ├── src/');
            console.log('   │   ├── components/');
            console.log('   │   ├── pages/');
            console.log('   │   ├── utils/');
            console.log('   │   └── App.js');
            console.log('   ├── public/');
            console.log('   ├── package.json');
            console.log('   └── README.md');
            
        } catch (error) {
            mainSpinner.fail('❌ 项目创建失败');
            console.error('错误详情:', error.message);
            process.exit(1);
        }
    }

    /**
     * 模拟项目初始化过程
     * @param {ora.Ora} spinner - ora进度条实例
     */
    async function simulateInitialization(spinner) {
        // 更新spinner文本
        spinner.text = '正在检查环境...';
        await sleep(1000); // 模拟检查环境
        
        spinner.text = '正在验证Node.js版本...';
        await sleep(800); // 模拟版本检查
        
        spinner.text = '正在创建项目根目录...';
        await sleep(1200); // 模拟创建目录
        
        spinner.text = '正在初始化Git仓库...';
        await sleep(1500); // 模拟Git初始化
    }

    /**
     * 创建目录结构
     * 使用嵌套的spinner显示子任务进度
     */
    async function createDirectoryStructure() {
        const dirs = ['src', 'src/components', 'src/pages', 'src/utils', 'public'];
        
        for (const dir of dirs) {
            const spinner = ora(`正在创建目录: ${dir}`).start();
            try {
                await fs.mkdir(dir, { recursive: true }); // 创建目录（如果不存在）
                await sleep(300); // 模拟创建时间
                spinner.succeed(`✅ 目录创建成功: ${dir}`);
            } catch (error) {
                spinner.fail(`❌ 目录创建失败: ${dir}`);
                throw error;
            }
        }
    }

    /**
     * 创建配置文件
     * 演示如何处理多个文件的创建进度
     */
    async function createConfigFiles() {
        const files = [
            { name: 'package.json', content: generatePackageJson() },
            { name: 'README.md', content: generateReadme() },
            { name: 'src/App.js', content: generateAppJs() },
            { name: 'public/index.html', content: generateIndexHtml() }
        ];
        
        const spinner = ora('正在创建配置文件...').start();
        
        for (let i = 0; i < files.length; i++) {
            const file = files[i];
            spinner.text = `正在创建文件: ${file.name} (${i + 1}/${files.length})`;
            
            try {
                // 确保目录存在
                const dir = path.dirname(file.name);
                await fs.mkdir(dir, { recursive: true });
                
                // 写入文件
                await fs.writeFile(file.name, file.content, 'utf8');
                await sleep(200); // 模拟文件写入时间
            } catch (error) {
                spinner.fail(`❌ 文件创建失败: ${file.name}`);
                throw error;
            }
        }
        
        spinner.succeed(`✅ 配置文件创建完成 (${files.length} 个文件)`);
    }

    /**
     * 安装依赖
     * 演示如何处理长时间运行的任务
     */
    async function installDependencies() {
        const spinner = ora('正在安装项目依赖...').start();
        
        try {
            // 模拟npm install过程
            spinner.text = '正在解析依赖关系...';
            await sleep(2000);
            
            spinner.text = '正在下载依赖包...';
            await sleep(3000);
            
            spinner.text = '正在构建依赖...';
            await sleep(1500);
            
            spinner.text = '正在验证安装...';
            await sleep(800);
            
            spinner.succeed('✅ 依赖安装完成');
        } catch (error) {
            spinner.fail('❌ 依赖安装失败');
            throw error;
        }
    }

    /**
     * 生成package.json内容
     * @returns {string} package.json文件内容
     */
    function generatePackageJson() {
        return `{
  "name": "my-react-app",
  "version": "1.0.0",
  "description": "使用脚手架创建的React应用",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}`;
    }

    /**
     * 生成README.md内容
     * @returns {string} README.md文件内容
     */
    function generateReadme() {
        return `# My React App

这是一个使用脚手架创建的React应用。

## 开始使用

\`\`\`bash
npm start
\`\`\`

## 构建项目

\`\`\`bash
npm run build
\`\`\`

## 运行测试

\`\`\`bash
npm test
\`\`\`
`;
    }

    /**
     * 生成App.js内容
     * @returns {string} App.js文件内容
     */
    function generateAppJs() {
        return `import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>欢迎使用React!</h1>
        <p>这是一个使用脚手架创建的应用。</p>
      </header>
    </div>
  );
}

export default App;
`;
    }

    /**
     * 生成index.html内容
     * @returns {string} index.html文件内容
     */
    function generateIndexHtml() {
        return `<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="使用脚手架创建的React应用" />
    <title>React App</title>
  </head>
  <body>
    <noscript>您需要启用JavaScript才能运行此应用。</noscript>
    <div id="root"></div>
  </body>
</html>`;
    }

    /**
     * 工具函数：延迟执行
     * @param {number} ms - 延迟毫秒数
     * @returns {Promise} Promise对象
     */
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 演示ora的高级用法
     * 包括自定义spinner、颜色、文本更新等
     */
    function demonstrateAdvancedOra() {
        console.log('\n🔧 Ora高级用法演示：\n');
        
        // 自定义spinner
        const customSpinner = ora({
            text: '自定义spinner演示',
            spinner: 'dots2', // 使用不同的spinner样式
            color: 'yellow' // 设置颜色
        }).start();
        
        setTimeout(() => {
            customSpinner.text = '正在处理数据...';
        }, 1000);
        
        setTimeout(() => {
            customSpinner.text = '正在保存结果...';
        }, 2000);
        
        setTimeout(() => {
            customSpinner.succeed('✅ 自定义spinner完成');
        }, 3000);
        
        // 演示警告状态
        setTimeout(() => {
            const warningSpinner = ora('这是一个警告示例').start();
            setTimeout(() => {
                warningSpinner.warn('⚠️ 警告：某些操作可能需要用户确认');
            }, 1000);
        }, 3500);
        
        // 演示信息状态
        setTimeout(() => {
            const infoSpinner = ora('正在获取信息...').start();
            setTimeout(() => {
                infoSpinner.info('ℹ️ 信息：已获取到最新数据');
            }, 1000);
        }, 4500);
    }

    // 如果直接运行此脚本，则执行脚手架
    if (require.main === module) {
        scaffold().then(() => {
            // 演示高级用法
            demonstrateAdvancedOra();
        }).catch(error => {
            console.error('脚手架执行失败:', error);
            process.exit(1);
        });
    }

    module.exports = { scaffold };
})(); 